package com.easylinkin.linkappapi.mechanical.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.easylinkin.linkappapi.application.service.ApplicationService;
import com.easylinkin.linkappapi.common.model.RequestModel;
import com.easylinkin.linkappapi.device.constant.DeviceConstant;
import com.easylinkin.linkappapi.device.entity.Device;
import com.easylinkin.linkappapi.device.service.DeviceService;
import com.easylinkin.linkappapi.device.vo.DeviceTypeCountVo;
import com.easylinkin.linkappapi.devicetype.entity.DeviceType;
import com.easylinkin.linkappapi.deviceunit.entity.DeviceUnit;
import com.easylinkin.linkappapi.mechanical.entity.EquipmentLocation;
import com.easylinkin.linkappapi.mechanical.entity.EquipmentLocationData;
import com.easylinkin.linkappapi.mechanical.entity.Mechanical;
import com.easylinkin.linkappapi.mechanical.service.IEquipmentLocationDataService;
import com.easylinkin.linkappapi.mechanical.service.IEquipmentLocationService;
import com.easylinkin.linkappapi.mechanical.service.IMechanicalService;
import com.easylinkin.linkappapi.mechanical.vo.EquipmentLocationVo;
import com.easylinkin.linkappapi.security.context.LinkappUserContextProducer;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import site.morn.rest.RestBuilders;
import site.morn.rest.RestMessage;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 铁路设备设施定位表
 *
 * @author xy
 * @since 2025-06-11
 */
@Api(tags = "铁路设备设施定位表")
@RestController
@RequestMapping("/mechanical/equipmentLocation")
public class EquipmentLocationController {
    @Autowired
    private IEquipmentLocationService equipmentLocationService;

    @Resource
    private LinkappUserContextProducer linkappUserContextProducer;

    @Resource
    private DeviceService deviceService;

    @Resource
    private IMechanicalService mechanicalService;

    @Resource
    private IEquipmentLocationDataService equipmentLocationDataService;

    /**
     * 设备类型列表
     *
     * @return
     */
    @ApiOperation(value="设备类型列表", notes="设备类型列表")
    @GetMapping(value = "/equipmentTypeList")
    public RestMessage equipmentTypeList() {
        List<DeviceType> deviceTypeList = getDeviceTypes();
        return RestBuilders.successBuilder(deviceTypeList).build();
    }

    /**
     * 分页列表查询
     *
     * @param requestModel
     * @return
     */
    @ApiOperation(value="分页列表查询", notes="分页列表查询")
    @PostMapping(value = "/listPage")
    public RestMessage queryPageList(@RequestBody RequestModel<EquipmentLocationVo> requestModel) {
        IPage<EquipmentLocation> pageList = equipmentLocationService.listPage(requestModel);
        return RestBuilders.successBuilder().data(pageList).build();
    }

    /**
     * 保存
     *
     * @param equipmentLocation
     * @return
     */
    @ApiOperation(value="保存", notes="保存")
    @PostMapping(value = "/save")
    public RestMessage save(@RequestBody EquipmentLocation equipmentLocation) {
        if(StrUtil.isNotEmpty(equipmentLocation.getEquipmentId())){
            String equipmentId = equipmentLocation.getEquipmentId();
            QueryWrapper<EquipmentLocation> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("equipment_id_",equipmentId);
            equipmentLocationService.remove(queryWrapper);
        }
        setBase(equipmentLocation);
        equipmentLocationService.save(equipmentLocation);
        return RestBuilders.successBuilder().message("保存成功" ).build();
    }

    /**
     * 设置基本属性
     *
     * @param equipmentLocation
     */
    private void setBase(EquipmentLocation equipmentLocation) {
        if (equipmentLocation.getLocationType() == 1) {
            equipmentLocation.setEquipmentLng(null);
            equipmentLocation.setEquipmentLat(null);
        }
        equipmentLocation.setModifyTime(new Date());
        equipmentLocation.setModifyId(linkappUserContextProducer.getCurrent().getId());
        //没有id就是新增,有就是编辑
        if (StringUtils.isBlank(equipmentLocation.getId())) {
            equipmentLocation.setCreateId(linkappUserContextProducer.getCurrent().getId());
            equipmentLocation.setCreateTime(new Date());
            equipmentLocation.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
        }
    }

    /**
     * 批量提交
     *
     * @param equipmentLocationList
     * @return
     */
    @ApiOperation(value="批量提交", notes="批量提交")
    @PostMapping(value = "/saveBatch")
    public RestMessage saveBatch(@RequestBody List<EquipmentLocation> equipmentLocationList) {
        if(CollUtil.isEmpty(equipmentLocationList)) {
            return RestBuilders.errorBuilder().message("参数不能为空").build();
        }
        for (EquipmentLocation equipmentLocation : equipmentLocationList) {
            if(StrUtil.isNotEmpty(equipmentLocation.getEquipmentId())){
                String equipmentId = equipmentLocation.getEquipmentId();
                QueryWrapper<EquipmentLocation> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("equipment_id_",equipmentId);
                equipmentLocationService.remove(queryWrapper);
            }
            setBase(equipmentLocation);
            equipmentLocationService.save(equipmentLocation);
        }
        return RestBuilders.successBuilder().message("批量提交成功").build();
    }

    /**
     * 通过id删除
     *
     * @param id
     * @return
     */
    @ApiOperation(value="通过id删除", notes="通过id删除")
    @DeleteMapping(value = "/delete")
    public RestMessage delete(@RequestParam("id") Integer id) {
        equipmentLocationService.removeById(id);
        return RestBuilders.successBuilder().message("删除成功").build();
    }

    /**
     *  批量删除
     *
     * @param ids
     * @return
     */
    @ApiOperation(value="批量删除", notes="批量删除")
    @DeleteMapping(value = "/deleteBatch")
    public RestMessage deleteBatch(@RequestParam("ids") String ids) {
        this.equipmentLocationService.removeByIds(Arrays.asList(ids.split(",")));
        return RestBuilders.successBuilder().message("批量删除成功").build();
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    @ApiOperation(value="通过id查询", notes="通过id查询")
    @GetMapping(value = "/queryById")
    public RestMessage queryById(@RequestParam("id") Integer id) {
        EquipmentLocation equipmentLocation = equipmentLocationService.getById(id);
        if(equipmentLocation == null) {
            return RestBuilders.errorBuilder().message("未找到对应数据").build();
        }
        return RestBuilders.successBuilder().data(equipmentLocation).build();
    }

    // 根据条件查询轨迹
    @ApiOperation(value="通过条件查询轨迹", notes="通过条件查询轨迹")
    @GetMapping(value = "/queryByCondition")
    public RestMessage queryByCondition(@RequestParam("equipmentId") String equipmentId, @RequestParam("startTime") String startTime, @RequestParam(value = "endTime", required = false) String endTime) {
        QueryWrapper<EquipmentLocation> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("equipment_id_",equipmentId);
        EquipmentLocation equipmentLocation = equipmentLocationService.getOne(queryWrapper);
        if(equipmentLocation == null) {
            return RestBuilders.errorBuilder().message("未找到对应数据").build();
        }
        if (StrUtil.isNotEmpty(endTime)) {
            LambdaQueryWrapper<EquipmentLocationData> wrapper = getQueryWrapper(equipmentId, equipmentLocation.getTenantId());
            wrapper.orderByDesc(EquipmentLocationData::getLocationTime);
            wrapper.between(EquipmentLocationData::getLocationTime, startTime, endTime);
            List<EquipmentLocationData> equipmentLocationDataList = equipmentLocationDataService.list(wrapper);
            return RestBuilders.successBuilder().data(equipmentLocationDataList).build();
        } else {
            LambdaQueryWrapper<EquipmentLocationData> wrapper = getQueryWrapper(equipmentId, equipmentLocation.getTenantId());
            wrapper.orderByDesc(EquipmentLocationData::getLocationTime);
            // 前后三个点作为轨迹startTime时间的三个点
            wrapper.ge(EquipmentLocationData::getLocationTime, startTime);
            wrapper.orderByAsc(EquipmentLocationData::getLocationTime);
            wrapper.last("LIMIT 3");
            List<EquipmentLocationData> afterList = equipmentLocationDataService.list(wrapper);
            LambdaQueryWrapper<EquipmentLocationData> wrapper1 = getQueryWrapper(equipmentId, equipmentLocation.getTenantId());
            wrapper1.lt(EquipmentLocationData::getLocationTime, startTime);
            wrapper1.orderByDesc(EquipmentLocationData::getLocationTime);
            wrapper1.last("LIMIT 3");
            List<EquipmentLocationData> beforeList = equipmentLocationDataService.list(wrapper1);
            // 合并两个list
            List<EquipmentLocationData> resultList = new ArrayList<>();
            resultList.addAll(beforeList);
            resultList.addAll(afterList);
            resultList.sort(Comparator.comparing(EquipmentLocationData::getLocationTime));
            return RestBuilders.successBuilder().data(resultList).build();
        }

    }

    private LambdaQueryWrapper<EquipmentLocationData> getQueryWrapper(String equipmentId, String tenantId) {
        LambdaQueryWrapper<EquipmentLocationData> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(EquipmentLocationData::getTenantId, tenantId);
        wrapper.eq(EquipmentLocationData::getEquipmentId, equipmentId);
        wrapper.eq(EquipmentLocationData::getMoveFlag, 1);
        wrapper.orderByDesc(EquipmentLocationData::getLocationTime);
        return wrapper;
    }



    /**
     * 全景感知-设备统计
     */
    @ApiOperation(value="全景感知-设备统计", notes="全景感知-设备统计")
    @GetMapping("deviceStatistics")
    public RestMessage deviceStatistics() {
        //设备分类
        List<DeviceType> deviceTypes = getDeviceTypes();
        //各个分类的设备统计
        RequestModel<EquipmentLocationVo> requestModel = new RequestModel<>();
        requestModel.setPage(new Page<>(1,-1));
        EquipmentLocationVo locationVo = new EquipmentLocationVo();
        locationVo.setTypeNames(deviceTypes.stream().map(DeviceType::getName).collect(Collectors.toList()));
        requestModel.setCustomQueryParams(locationVo);
        IPage<EquipmentLocation> page = equipmentLocationService.listPage(requestModel);
        List<EquipmentLocation> equipmentLocationList = page.getRecords();
        //设备分类统计
        List<Map<String, Object>> result = new ArrayList<>();
        //按设备分类匹配设置对应的设备
        for (DeviceType deviceType : deviceTypes) {
            Map<String, Object> typeMap = new HashMap<>();
            typeMap.put("typeName", deviceType.getName());

            // 筛选出该类型的设备集合
            List<EquipmentLocation> equipmentList = equipmentLocationList.stream()
                    .filter(equipment -> deviceType.getName().equals(equipment.getEquipmentTypeName()))
                    .collect(Collectors.toList());

            //如果 equipmentType -1 那么是机械设备
            if("-1".equals(deviceType.getId())){
                //只取在场的
                equipmentList = equipmentList.stream()
                        .filter(equipment -> Integer.valueOf(0).equals(equipment.getStatus()))
                        .collect(Collectors.toList());
            }
            typeMap.put("equipmentList", equipmentList);
            result.add(typeMap);
        }

        return RestBuilders.successBuilder().data(result).build();
    }

    /**
     * 获取设备分类
     * @return
     */
    private List<DeviceType> getDeviceTypes() {
        List<DeviceType> deviceTypeList = new ArrayList<>();
        List<DeviceTypeCountVo> statisticsExistDeviceByType = deviceService.getStatisticsExistDeviceByType(new Device());
        Map<String, Integer> deviceTypeCountMap = statisticsExistDeviceByType.stream().collect(Collectors.toMap(m -> m.getDeviceTypeName(), m -> m.getDeviceCount()));
        for (DeviceConstant.RailwayDeviceType value : DeviceConstant.RailwayDeviceType.values()) {
            String deviceTypeName = value.getDescription();
            // 设备数量为0，不显示
            DeviceType dt =new DeviceType();
            dt.setId(value.getType().toString());
            dt.setName(deviceTypeName);
            if(deviceTypeCountMap.containsKey(deviceTypeName)&&deviceTypeCountMap.get(deviceTypeName)>0) {
                dt.setCount(deviceTypeCountMap.get(deviceTypeName));
            }
            deviceTypeList.add(dt);
        }
        // 机械数量为0，不显示
        LambdaQueryWrapper<Mechanical> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Mechanical::getTenantId, linkappUserContextProducer.getNotNullCurrent().getTenantId());
        int count = mechanicalService.count(queryWrapper);
        DeviceType dt1 =new DeviceType();
        dt1.setId("-1");
        dt1.setName("机械");
        if(count>0) {
            dt1.setCount(count);
        }
        deviceTypeList.add(dt1);
        return deviceTypeList;
    }
}
